package com.basker.pisces.utils;

import org.springframework.util.Assert;

public class ExceptionUtils {

    /**
     * throwable的异常链中，是否存在匹配的异常类型
     *
     * @param chain
     * @param type
     * @return
     */
    public static boolean causeBy(Throwable chain, final Class<? extends Throwable> type) {
        return findCause(chain, type) != null;
    }

    /**
     * throwable的异常链中，尝试获取匹配类型的异常对象，找不到返回null
     *
     * @param <T>
     * @param chain
     * @param type
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T extends Throwable> T findCause(Throwable chain, final Class<T> type) {
        Assert.notNull(chain, "parameter 'throwable' is requried");
        Assert.notNull(type, "parameter 'type' is requried");

        Throwable cause = chain;

        while (true) {
            if (type.isInstance(cause)) {
                return (T) cause;
            }

            cause = cause.getCause();
            if (cause == null) {
                return null;
            }
        }
    }
}
